/**
 * 
 */
package com.wistech.search.solr.handler;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Query;
import org.apache.solr.common.SolrInputField;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.RequestHandlerUtils;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.QueryParsing;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.util.plugin.SolrCoreAware;

import com.wistech.search.solr.score.ExpressionXscorerFactory;
import com.wistech.search.solr.score.XscorerFactory;
import com.wistech.utils.MathUtils;

/**
 * @author Liuye
 * 
 */
public class XscorerHandler extends RequestHandlerBase implements SolrCoreAware {
	public static final String ENABLE_DEBUG = "enableDebug";
	private static final String COMMAND_RECONFIG = "rc";
	private static final String COMMAND_RELOAD_DATA = "rd";
	private static final String COMMAND_GET = "get";
	private static final String COMMAND_CALC = "calc";

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.solr.util.plugin.SolrCoreAware#inform(org.apache.solr.core
	 * .SolrCore)
	 */
	@Override
	public void inform(SolrCore core) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.solr.handler.RequestHandlerBase#handleRequestBody(org.apache
	 * .solr.request.SolrQueryRequest,
	 * org.apache.solr.response.SolrQueryResponse)
	 */
	@Override
	public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp)
			throws Exception {
		rsp.setHttpCaching(false);
		SolrParams params = req.getParams();

		String cmd = params.get("command");
		if (cmd == null) {
			cmd = params.get("cmd");
		}
		final XscorerFactory xFactory = req.getCore().getSchema()
				.getXscorerFactory();
		String message = "";
		if (xFactory == null) {
			message = "the XscorerFactory in schema is null.";
			rsp.add("importResponse", message);
			RequestHandlerUtils.addExperimentalFormatWarning(rsp);
			return;
		}
		if (cmd == null) {
			message = "command is null.";
		} else if (COMMAND_RECONFIG.equals(cmd) && !xFactory.isBusy()) {
			xFactory.reConfigure();
			message = "XscorerFactory's configuration re-loaded sucessfully";
		} else if (COMMAND_RELOAD_DATA.equals(cmd) && !xFactory.isBusy()) {
			new Thread() {
				@Override
				public void run() {
					xFactory.refresh();
				}
			}.start();
			message = "Refresh Xscorer Data...";
		} else if (COMMAND_GET.equals(cmd)) {
			if (xFactory instanceof ExpressionXscorerFactory) {
				Long id = Long.parseLong(params.get("id"));
				float score = ((ExpressionXscorerFactory) xFactory)
						.getBizScore(id);
				message = String.valueOf(score);
			}
		} else if (COMMAND_CALC.equals(cmd)) {
			if (xFactory instanceof ExpressionXscorerFactory) {

				Long id = Long.parseLong(params.get("id"));
				Term term = new Term("id", String.valueOf(id));
				SolrIndexSearcher searcher = req.getSearcher();
				int docId = searcher.getFirstMatch(term);
				if (docId != -1) {
					Map<String, Object> model = new HashMap<String, Object>();
					Document doc = searcher.doc(docId);
					for (Fieldable field : doc.getFields()) {
						if (field.isStored()) {
							String stringValue = field.stringValue();
							if (MathUtils.isNumeric(stringValue, true)) {
								model.put(field.name(),
										Float.parseFloat(stringValue));
							}
						}
					}
					float score = ((ExpressionXscorerFactory) xFactory)
							.getScoreExpression().eval(model);
				}
			}
		} else if (xFactory.isBusy()) {
			message = "A command is still running...";
		} else {
			message = "invalid command.";
		}
		rsp.add("statusMessage", xFactory.isBusy() ? "busy" : "idle");
		rsp.add("importResponse", message);
		rsp.add("statusMessages", xFactory.getStatusMessage());
		RequestHandlerUtils.addExperimentalFormatWarning(rsp);

	}

	// //////////////////////SolrInfoMBeans methods //////////////////////

	@Override
	public String getDescription() {
		return "Reconfigure or refresh XscorerFactory.";
	}

	@Override
	public String getSourceId() {
		return "$Id: XscorerHandler.java 1095447 2011-08-06 16:16:06Z StevenLiu $";
	}

	@Override
	public String getVersion() {
		return "1.0";
	}

	@Override
	public String getSource() {
		return "$URL: http://www.moshiling.com/svn/trunk/b2b-solr/src/main/java/com/moshiling/search/solr/handler/XscorerHandler.java $";
	}
}
